It’s difficult to work with Groovy and Tempo fields, because we need to use always the REST interface to work with them (Tempo Team customfield and Tempo Account customfield).
Here we can see an example of how to set these customfields using scripting in a PostFunction created in groovy (with the plugin Adaptavist Scriptrunner).
In the example, we use two different classes of call, one using the usual Groovy classes and other one that runs on server and call in the bash shell the CURL famous executable.
With CURL we can get API calls…, but also we can get HTML from screens! And this is awesome!
- We wrote something a long time ago here How to get the required team hours from JIRA Tempo plugin with groovy
- And here Groovy REST WS call example to TEMPO JIRA plugin
- JIRA REST API Example with CURL
And now the script PostFunction example to set Tempo Team and Account!
def JIRA_REST_URL = "http://localhost:2000" def JIRA_API_URL = JIRA_REST_URL + "/rest/tempo-teams/1/team" def JIRA_API_URL_2 = JIRA_REST_URL + "/rest/tempo-accounts/1/account" def JIRA_API_URL_3 = JIRA_REST_URL + "/rest/api/2/issue/" def campo_account_id = "customfield_xxxx" //Account Tempo field id def user_password ="user:password" //To execute the actions, the user must have permissions import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.issue.customfields.view.CustomFieldParams import com.atlassian.jira.issue.customfields.option.Option import com.atlassian.jira.issue.customfields.view.CustomFieldParams import com.atlassian.jira.issue.customfields.impl.CascadingSelectCFType import com.atlassian.jira.issue.Issue import com.atlassian.jira.issue.MutableIssue import com.atlassian.jira.issue.comments.CommentManager import com.atlassian.jira.project.Project import org.apache.log4j.Category import com.atlassian.jira.bc.project.component.* import groovyx.net.http.HTTPBuilder import org.apache.http.HttpRequestInterceptor; import org.apache.http.HttpRequest; import org.apache.http.protocol.HttpContext; import groovy.json.JsonSlurper; import com.atlassian.jira.issue.IssueManager; import groovyx.net.http.ContentType; import groovyx.net.http.Method.*; log.setLevel(org.apache.log4j.Level.DEBUG) log.debug "DEBUG ENABLED" IssueManager issueMgr = ComponentAccessor.getIssueManager(); def customFieldMananger = ComponentAccessor.getCustomFieldManager() def field_team = customFieldMananger.getCustomFieldObjectByName("Team") def field_account = customFieldMananger.getCustomFieldObjectByName("Account") //We get the current issue of the PostFunction MutableIssue issue2 = issue def jira = new HTTPBuilder(JIRA_API_URL); jira.client.addRequestInterceptor(new HttpRequestInterceptor() { void process(HttpRequest httpRequest, HttpContext httpContext) { httpRequest.addHeader('Authorization', 'Basic ' + user_password.bytes.encodeBase64().toString()) } }) def teams = jira.get(path: JIRA_API_URL ); def team_id = ""; for ( int i = 0; i < teams.size(); i++ ) { if ( "team to set" == teams[i].name) team_id = teams[i].id } issue2.setCustomFieldValue(field_team, "" + team_id) def jira2 = new HTTPBuilder(JIRA_API_URL_2); jira2.client.addRequestInterceptor(new HttpRequestInterceptor() { void process(HttpRequest httpRequest, HttpContext httpContext) { httpRequest.addHeader('Authorization', 'Basic ' + user_password.bytes.encodeBase64().toString()) } }) def accounts = jira2.get(path: JIRA_API_URL_2 ); def account_id = ""; def account_key = ""; for ( int i = 0; i < accounts.size(); i++ ) { if ( "account to set" == accounts[i].name) { account_id = accounts[i].id account_key = accounts[i].key } } //We use CURL (executable program installed in the system) to set the Tempo Account field in the Jira ticket (another way to do REST queries) def sout = new StringBuilder(), serr = new StringBuilder() def query = '{"fields":{"'+campo_account_id+'":"'+account_id+'"}}' def proc = [ 'bash', '-c',("curl -D- -u "+user_password+" -X PUT --data '"+query+"' -H "+'"Content-Type:application/json"'+" "+ JIRA_API_URL_3 + issue2.getKey())].execute() proc.consumeProcessOutput(sout, serr) def error = proc.waitFor(); def texto = sout.toString(); def texto2 = serr.toString(); log.debug(texto + "::" + texto2) issue2.store()
Hi,
Thanks for script I need this to resolve problem with Invalid Worklogs in Tempo after moving issue to another project. I wrote my own script based on yours, but not work properly. I use My Groovy addon and I use CURL to serach and update date in Jira by REST API. My script find properly information in Jira, but I have problem with update a account filed. It’s look like curl2 isn’t execute. Can you take a look on my script and tell my where is a problem? I have another script listener where i execute curl command many time in one script and it’s work good. My Jira is install on Windows Server.
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.issue.IssueEvent
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.label.LabelManager
import com.atlassian.jira.issue.util.IssueChangeHolder;
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue
import groovy.json.JsonSlurper
def JIRA_API_URL = (“https://myjira.eu/rest/api/latest/issue/”)
def user_password = “user:password”
def accountCf = “customfield_11110”
def commentManager = ComponentAccessor.commentManager
def cfm = ComponentAccessor.getCustomFieldManager()
def userManager = ComponentAccessor.getUserManager()
def user = userManager.getUserByKey(“user”)
def issue= event.getIssue()
def projId = issue.getProjectId().toString()
def issueKey = issue.getKey().toString()
def curl = “E:/curl/bin/curl.exe -u user:password https://myjira.eu/rest/tempo-accounts/1/account/project/${projId}”
def output = curl.execute().text
def slurper = new groovy.json.JsonSlurper()
def results = slurper.parseText(output)
def id = results.id.toString()
def accountId = id.substring(1, id.length() – 1)
def sout = new StringBuilder(), serr = new StringBuilder()
def query = ‘{“””fields”””:{“””‘+accountCf+'”””:”””‘+accountId+'”””}}’
def curl2 = [ ‘E:/curl/bin/curl.exe’,(” -u “+user_password+” -X PUT –data “+query+” -H “+'”Content-Type:application/json”‘+” “+ JIRA_API_URL+issueKey)].execute()
curl2.consumeProcessOutput(sout, serr)
def error = curl2.waitFor();
def texto = sout.toString();
def texto2 = serr.toString();
log.debug(texto + “::” + texto2)
issue.store()
LikeLike
Hello!
Try to use HTTPBuilder class to update the Account field
Example:
Best regards!
LikeLike
HTTPBuilder doesn’t work in My Groovy. I try update Account field via HttpURLConnection but this doesn’t work to. I have no ida what is wrong
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.issue.IssueEvent
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.label.LabelManager
import com.atlassian.jira.issue.util.IssueChangeHolder;
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue
import java.nio.charset.StandardCharsets
import groovy.json.JsonSlurper
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Base64;
def user_password = “user:password”
def accountCf = “customfield_11110”
def commentManager = ComponentAccessor.commentManager
def cfm = ComponentAccessor.getCustomFieldManager()
def userManager = ComponentAccessor.getUserManager()
def user = userManager.getUserByKey(“user”)
def issue= event.getIssue()
def projId = issue.getProjectId().toString()
def issueKey = issue.getKey().toString()
def curl = “E:/curl/bin/curl.exe -u user:password https://myjira.eu/rest/tempo-accounts/1/account/project/${projId}”
def output = curl.execute().text
def slurper = new groovy.json.JsonSlurper()
def results = slurper.parseText(output)
def id = results.id.toString()
def accountId = id.substring(1, id.length() – 1)
def sout = new StringBuilder(), serr = new StringBuilder()
HttpURLConnection connection = null;
URL jiraURL = new URL (“https://myjira.eu/rest/api/latest/issue/${issueKey}”)
def query =”{\n” +
” \”fields\”: {\n” +
” \”customfield_11110\”: \”${accountId}\”\n” +
” }\n” +
“}”
byte[] dataBytes = query.getBytes(“UTF-8”)
String login = “user:password”
final byte[] authBytes = login.getBytes(StandardCharsets.UTF_8)
String encoded = Base64.getEncoder().withoutPadding().encodeToString(authBytes)
connection = (HttpURLConnection) jiraURL.openConnection();
connection.requestMethod = “POST”
connection.setRequestProperty(“Accept”, “*/*”)
connection.setRequestProperty(“Content-Type”, “application/json”)
connection.setRequestProperty(“Authorization”, “Basic ” + encoded)
connection.setUseCaches(false)
connection.doOutput = (true)
connection.doInput = (true)
connection.connect()
DataOutputStream wr = new DataOutputStream(connection.getOutputStream())
wr.write(dataBytes)
wr.flush()
wr.close()
LikeLike
Another thing, if finally you use CURL to extract the info, we recommend to use a “script proxy” in the server. See this example: https://mraddon.blog/2016/06/16/how-to-get-the-required-team-hours-from-jira-tempo-plugin-with-groovy/
LikeLike
Hello!
You must investigate first the error in the atlassian-jira.log in the logs folder of the Jira-home directory
Add the log4java libraries (just an import)
import org.apache.log4j.Category
Set the log to DEBUG mode
def Category log = Category.getInstance(“com.onresolve.jira.groovy”)
log.setLevel(org.apache.log4j.Level.DEBUG)
Add traces and result variables to the usual Jira log (atlassian-jira.log)
Examples:
log.debug “debug statements”
log.warn(“Logging!”)
log.error(“Logging!”)
log.fatal(“Logging!”)
Best regards!
LikeLike
Love to have this same code without all the CURL part…
LikeLiked by 1 person